import cv2
import face_recognition


class FaceLandmarks(object):
    def __init__(self,scaling_factor=0.25,extract_face=True):
        self._scaling_factor=scaling_factor     # 图片缩放因子,默认是0.25
        if extract_face==True:
            self._extract=extractFaceLocationAndLipFeature
        else:
            self._extract = extractLipFeature

    def extractLandmarks(self, frame):
        """
        提取相应特征
        :param frame: 原始图片
        :return:
        """
        # 将图片缩小
        if self._scaling_factor<1 and self._scaling_factor>0:
            frame = cv2.resize(frame, (0, 0),
                               fx=self._scaling_factor, fy=self._scaling_factor)
        rgb_frame =frame[:, :, ::-1]  # 将BGR转化为RGB
        landmarks=self._extract(rgb_img=rgb_frame,
                                scaling_factor=self._scaling_factor)
        return landmarks


def extractLipFeature(rgb_img,scaling_factor):
    # 提取唇部特征位置
    face_landmarks_list = face_recognition.face_landmarks(rgb_img)
    lip_features = lipFeatureProcessing(face_landmarks_list,
                                        scaling_factor)  # 对特征进行处理
    return lip_features


def extractFaceLocationAndLipFeature(rgb_img,scaling_factor):
    # 提取人脸坐标和唇部特征位置
    face_locations = face_recognition.face_locations(rgb_img)   # 获取人脸区域坐标
    # 获取唇部特征点位置
    face_landmarks_list=[]
    for location in face_locations:
        face_landmarks = face_recognition.face_landmarks(
            rgb_img[location[0]:location[2],location[3]:location[1], :])  # 提取脸部特征
        if len(face_landmarks)!=0:
            face_landmarks_list.append(face_landmarks[0])
    lip_features = lipFeatureProcessing(face_landmarks_list,
                                        scaling_factor)  # 对特征进行处理
    return face_locations,lip_features


def lipFeatureProcessing(face_landmarks_list, scaling_factor=1):
    """
     # 从脸部特征集提取唇部特征
    :param face_landmarks_list: list,每个元素为一个人脸部特征集dict
    :return:
    """
    lip_features=[]
    scaling_factor = int(1 / scaling_factor)
    for face_landmarks in face_landmarks_list:
        top_lip=[(point[0]*scaling_factor,point[1]*scaling_factor) for point in face_landmarks["top_lip"]]
        bottom_lip=[(point[0]*scaling_factor,point[1]*scaling_factor) for point in face_landmarks["bottom_lip"]]
        lip_features.append(top_lip+bottom_lip)
    return lip_features


def normalization(features,width,hight):
    """
    对特征进行标准化
    :param features: 特征列表,list
    :param width: 图片的宽
    :param hight: 图片的高
    :return:
    """
    norm_feature_list=[]
    for feature in features:
        norm_feature = []
        for point in feature:
            norm_feature.append(point[0]/width)
            norm_feature.append(point[1]/hight)
        norm_feature_list.append(norm_feature)
    return norm_feature_list


# if __name__=="__main__":
#     image=cv2.imread("/home/lisen/tool/PyProjects/唇语识别/test_data/1.png")
#     print(image.shape)
#     face=FaceLandmarks()
#     lip_features=face.extractLipsFeature(image)
#     for feature in lip_features:
#         for point in feature:
#             cv2.circle(image,point,1,(0,0,255),-1)
#     cv2.imshow("",image)
#     cv2.waitKey()
